/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package br.com.foxline.clinicplus.manager;

import br.com.foxline.clinicplus.enums.Gender;
import br.com.foxline.clinicplus.enums.GroupProcedure;
import br.com.foxline.clinicplus.enums.PaymentType;
import br.com.foxline.clinicplus.enums.TypeCredit;
import br.com.foxline.clinicplus.enums.TypeDebt;
import br.com.foxline.clinicplus.enums.TypeIncome;
import br.com.foxline.clinicplus.enums.TypeProcedure;
import br.com.foxline.clinicplus.service.CustomerService;
import br.com.foxline.clinicplus.service.DiaryService;
import br.com.foxline.clinicplus.service.IncomeService;
import br.com.foxline.clinicplus.service.OperatorService;
import br.com.foxline.clinicplus.service.SystemUserService;
import java.io.Serializable;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;
import javax.annotation.PostConstruct;
import javax.ejb.EJB;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import org.primefaces.model.chart.CartesianChartModel;
import org.primefaces.model.chart.DonutChartModel;
import org.primefaces.model.chart.LineChartSeries;

/**
 *
 * @author roniere
 */
@ManagedBean
@ViewScoped
public class ManagerChartReport implements Serializable {

    @EJB
    SystemUserService systemUserService;
    @EJB
    CustomerService customerService;
    @EJB
    DiaryService diaryService;
    @EJB
    OperatorService operatorService;
    @EJB
    IncomeService incomeService;
    private DonutChartModel incomeDebt;
    private CartesianChartModel linearProcedureDate;
    private CartesianChartModel linearProcedureDateValue;
    private Long max;
    private Long maxValue;

    @PostConstruct
    public void init() {
        max = 0L;
        maxValue = 0L;
        incomeDebt = graficoGender();
        linearProcedureDate = initLinearModel();
        linearProcedureDateValue = initLinearModelValue();
    }

    public DonutChartModel graficoGender() {
        DonutChartModel model = new DonutChartModel();

        Map<String, Number> circle1 = new LinkedHashMap<String, Number>();

        for (TypeDebt td : TypeDebt.values()) {
            circle1.put(td.getDesc(), incomeService.getValueIncomeGeneric(null, null, null, null, null, null,
                    null, TypeIncome.D, td, null, null, null, null, null, null, null, null));
        }

        model.addCircle(circle1);

        return model;
    }

    private CartesianChartModel initLinearModel() {
        CartesianChartModel model = new CartesianChartModel();

        LineChartSeries series1 = new LineChartSeries("Consultas");
        LineChartSeries series2 = new LineChartSeries("Exames");

        Calendar gc = GregorianCalendar.getInstance();
        gc.set(GregorianCalendar.HOUR_OF_DAY, 0);
        gc.set(GregorianCalendar.DAY_OF_MONTH, 1);
        gc.set(GregorianCalendar.MINUTE, 0);
        gc.set(GregorianCalendar.SECOND, 0);
        gc.set(GregorianCalendar.MILLISECOND, 0);

        int mesAtual = gc.get(Calendar.MONTH);

        Calendar gc1 = GregorianCalendar.getInstance();
        gc1.set(GregorianCalendar.HOUR_OF_DAY, 0);
        gc1.set(GregorianCalendar.DAY_OF_MONTH, 1);
        gc1.set(GregorianCalendar.MINUTE, 0);
        gc1.set(GregorianCalendar.SECOND, 0);
        gc1.set(GregorianCalendar.MILLISECOND, 0);

        gc.set(GregorianCalendar.MONTH, 0);
        gc1.set(GregorianCalendar.MONTH, 1);

        Locale brasil = new Locale("pt", "BR");
        SimpleDateFormat sdf = new SimpleDateFormat("MMMMM", brasil);

        for (int i = 0; i < mesAtual; i++) {

            Long exame = diaryService.countDiaryForDate(gc.getTime(), gc1.getTime(), TypeProcedure.EXAME);
            Long consulta = diaryService.countDiaryForDate(gc.getTime(), gc1.getTime(), TypeProcedure.CONSULTA);
            if (max < exame) {
                max = exame;
            }
            if (max < consulta) {
                max = consulta;
            }

            series2.set(sdf.format(gc.getTime()), exame);
            series1.set(sdf.format(gc.getTime()), consulta);
            gc.set(GregorianCalendar.MONTH, gc1.get(Calendar.MONTH));
            gc1.set(GregorianCalendar.MONTH, i + 2);

        }
        max += 5;
        model.addSeries(series1);
        model.addSeries(series2);
        return model;
    }

     private CartesianChartModel initLinearModelValue() {
        CartesianChartModel model = new CartesianChartModel();

        LineChartSeries series1 = new LineChartSeries("Consultas");
        LineChartSeries series2 = new LineChartSeries("Exames");

        Calendar gc = GregorianCalendar.getInstance();
        gc.set(GregorianCalendar.HOUR_OF_DAY, 0);
        gc.set(GregorianCalendar.DAY_OF_MONTH, 1);
        gc.set(GregorianCalendar.MINUTE, 0);
        gc.set(GregorianCalendar.SECOND, 0);
        gc.set(GregorianCalendar.MILLISECOND, 0);

        int mesAtual = gc.get(Calendar.MONTH);

        Calendar gc1 = GregorianCalendar.getInstance();
        gc1.set(GregorianCalendar.HOUR_OF_DAY, 0);
        gc1.set(GregorianCalendar.DAY_OF_MONTH, 1);
        gc1.set(GregorianCalendar.MINUTE, 0);
        gc1.set(GregorianCalendar.SECOND, 0);
        gc1.set(GregorianCalendar.MILLISECOND, 0);

        gc.set(GregorianCalendar.MONTH, 0);
        gc1.set(GregorianCalendar.MONTH, 1);

        Locale brasil = new Locale("pt", "BR");
        SimpleDateFormat sdf = new SimpleDateFormat("MMMMM", brasil);

        for (int i = 0; i < mesAtual; i++) {

            BigDecimal exame = diaryService.getValueDiaryForDateToChart(gc.getTime(), gc1.getTime(), null, TypeIncome.C, 
                    TypeProcedure.EXAME);
            BigDecimal consulta = diaryService.getValueDiaryForDateToChart(gc.getTime(), gc1.getTime(), null, TypeIncome.C,
                    TypeProcedure.CONSULTA);
            
            if (exame != null && maxValue < exame.longValue()) {
                maxValue = exame.longValue();
            }
            if (consulta != null && maxValue < consulta.longValue()) {
                maxValue = consulta.longValue();
            }

            series2.set(sdf.format(gc.getTime()), exame == null ? 0 : exame.longValue());
            series1.set(sdf.format(gc.getTime()), consulta == null ? 0 : consulta.longValue());
            
            gc.set(GregorianCalendar.MONTH, gc1.get(Calendar.MONTH));
            gc.add(GregorianCalendar.DAY_OF_MONTH, 1);
            gc1.set(GregorianCalendar.MONTH, i + 2);

        }
        maxValue += 3000;
        model.addSeries(series1);
        model.addSeries(series2);
        return model;
    }

    public DonutChartModel getIncomeDebt() {
        return incomeDebt;
    }

    public void setIncomeDebt(DonutChartModel incomeDebt) {
        this.incomeDebt = incomeDebt;
    }

    public CartesianChartModel getLinearProcedureDate() {
        return linearProcedureDate;
    }

    public void setLinearProcedureDate(CartesianChartModel linearProcedureDate) {
        this.linearProcedureDate = linearProcedureDate;
    }

    public Long getMax() {
        return max;
    }

    public void setMax(Long max) {
        this.max = max;
    }

    public CartesianChartModel getLinearProcedureDateValue() {
        return linearProcedureDateValue;
    }

    public void setLinearProcedureDateValue(CartesianChartModel linearProcedureDateValue) {
        this.linearProcedureDateValue = linearProcedureDateValue;
    }

    public Long getMaxValue() {
        return maxValue;
    }

    public void setMaxValue(Long maxValue) {
        this.maxValue = maxValue;
    }
}
